package com.sxj.shop.listener;

import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
 * @author 石小俊
 * @date 2024年03月20日 20:26
 */
@WebListener
public class InlineCountListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent event) {
        System.out.println("***************创建session***************");
        // 获取application存在两种方式
        // 方式一:如果在Servlet中获取,可以直接获取
        // 在GenericServlet中提供了直接获取的方式,因此可以直接使用
        // ServletContext application = getServletContext();
        // 方拾二:通用型,可以通过request或者session进行获取
        HttpSession session = event.getSession();
        ServletContext application = session.getServletContext();

        // 由于此时可能存在无数个人同一时间同时访问服务器
        // 因此,此处存在线程同步问题
        synchronized (this) {
            // 取出application作用域中保存的在线人数数据
            Integer count = (Integer) application.getAttribute("count");
            // 如果是第一次访问,此时的作用域中尚未存在数据
            if (null == count) {
                // 因此可以设置一个初始值
                count = 1;
            } else {
                // 如果不是第一次访问,则在原有值的基础上+1
                count++;
            }
            // 将最新的在线人数数据保存到application作用域中
            application.setAttribute("count", count);
        }
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
        System.out.println("***************销毁session***************");
        HttpSession session = event.getSession();
        ServletContext application = session.getServletContext();

        // 由于此时可能存在无数个人同一时间同时访问服务器
        // 因此,此处存在线程同步问题
        synchronized (this) {
            Integer count = (Integer) application.getAttribute("count");
            count--;
            // 将最新的在线人数数据保存到application作用域中
            application.setAttribute("count", count);
        }
    }
}
